package com.smartsystem.common.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartsystem.common.service.TokenBlacklistService;
import com.smartsystem.common.utils.JWTUtils;
import com.smartsystem.common.utils.Result;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * JWT认证拦截器
 * 用于验证JWT Token的有效性和黑名单检查
 */
@Component
public class JwtAuthInterceptor implements HandlerInterceptor {
    
    @Resource
    private TokenBlacklistService tokenBlacklistService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 跳过OPTIONS请求
        if ("OPTIONS".equals(request.getMethod())) {
            return true;
        }
        
        // 获取Token
        String authHeader = request.getHeader("Authorization");
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            writeErrorResponse(response, 401, "未提供认证Token");
            return false;
        }
        
        String token = authHeader.substring(7);
        
        // 检查Token是否在黑名单中
        if (tokenBlacklistService.isBlacklisted(token)) {
            writeErrorResponse(response, 401, "Token已失效，请重新登录");
            return false;
        }
        
        // 验证Token是否有效
        if (!JWTUtils.validateToken(token)) {
            writeErrorResponse(response, 401, "Token无效或已过期");
            return false;
        }
        
        return true;
    }
    
    /**
     * 写入错误响应
     */
    private void writeErrorResponse(HttpServletResponse response, int code, String message) throws IOException {
        response.setStatus(code);
        response.setContentType("application/json;charset=UTF-8");
        
        Result<Object> result = Result.fail(code, message);
        String jsonResponse = objectMapper.writeValueAsString(result);
        
        response.getWriter().write(jsonResponse);
    }
}